/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package intopo.evogame.partnerselection;

import intopo.evogame.partnerselection.config.ConstructGameException;
import intopo.evogame.partnerselection.config.ConstructStrategyException;
import intopo.evogame.partnerselection.config.ParsingException;
import intopo.evogame.partnerselection.config.TagException;
import intopo.evogame.partnerselection.config.TextConfigFilePlainPlayersEvoGame;
import intopo.game.DescriptionText;

import java.io.FileNotFoundException;
import java.io.IOException;

/**
 *
 * @author <a href="mailto:mariano.pedro@gmail.com">Pedro Mariano</a>
 *
 * @version 1.0 __DATE__
 */
public class Main
{
	/**
	 * Name of the text configuration file to read.
	 */
	final private String configFilename;
	final private DescriptionText description;
	Main ()
	{
		this.configFilename = null;
		this.description = null;
	}
	Main (String[] args)
	{
		if (args.length == 2 || args.length == 3) {
			// parse game arguments
			if (args [0].equals ("-g")) {
				if (args [1].equals ("givetake") || args [1].equals ("gt")) {
					this.description = new intopo.game.impl.givetake.GiveTakeDescriptionTextGUI ();
				}
				else if (args [1].equals ("ipd")) {
					this.description = new intopo.game.impl.ipd.IteratedPrisonerDilemmaDescriptionTextGUI ();
				}
				else if (args [1].equals ("pgp")) {
					this.description = new intopo.game.impl.pgp.PublicGoodProvisionDescriptionTextGUI ();
				}
				else if (args [1].equals ("sym2x2")) {
					this.description = new intopo.game.impl.sym2x2.Sym2x2Description ();
				}
				else if (args [1].equals ("ultimatum")) {
					this.description = new intopo.game.impl.ultimatum.UltimatumDescriptionTextGUI ();
				}
				else {
					System.err.println ("Unknown game");
					this.description = null;
				}
			}
			else {
				System.err.println ("Unknown option: " + args [0]);
				this.description = null;
			}
			// parse config file name
			if (args.length == 3) {
				this.configFilename = args [2];
			}
			else {
				this.configFilename = "config.txt";
			}
		}
		else {
			if (args.length > 1) {
				System.err.println ("Invalid options");
			}
			else if (args.length == 1) {
				System.err.println ("Invalid options");
			}
			this.description = null;
			this.configFilename = null;
		}
	}

	private int run ()
	{
		if (this.description == null) {
			System.err.println ("Usage:\n  java Main -g GAME [CONFIG_FILE]\n where GAME is");
			System.err.println ("  givetake|gt  run the evolutionary algorithm using the Give-Take game");
			System.err.println ("  ipd          run the evolutionary algorithm using the Iterated Prisoner's Dilemma game");
			System.err.println ("  pgp          run the evolutionary algorithm using the Public Good Provision game");
			System.err.println ("  sym2x2       run the evolutionary algorithm using a symmetric 2-player 2 action game");
			System.err.println ("  ultimatum    run the evolutionary algorithm using the Ultimatum game");
			return 1;
		}
		// open the database
		try {
			Database.singleton.open (false);
		}
		catch (FileNotFoundException ex) {
			System.err.println ("Error opening the database");
			return 2;
		}
		// read the configuration file
		TextConfigFilePlainPlayersEvoGame config;
		config = new TextConfigFilePlainPlayersEvoGame (this.description);
		try {
			config.read (configFilename);
		}
		catch (ParsingException e) {
			System.err.println ("Error parsing configuration file + '" + this.configFilename + "'");
			System.err.println ("Reading '" + e.getLocalizedMessage () + "'");
			if (e.getContents () == null) {
				System.err.println ("No line available");
			}
			else {
				System.err.println ("at line '" + e.getContents () + "'");
			}
			return 3;
		}
		catch (FileNotFoundException ex) {
			System.err.println ("Configuration file '" + this.configFilename
					  + "' not found");
			return 3;
		}
		catch (TagException ex) {
			System.err.println (ex.getUserMessage ());
//			"Error reading configuration file.  Tag '"
//				+ ex.getTag ()
//				+ "' does not correspond to any constructor in game '"
//				+ this.description.getClass ().getName ());
			return 3;
		}
		catch (ConstructGameException ex) {
			System.err.println ("Error creating the instance of game '"
				+ this.description.getClass ().getName ()
				+ "\nCause was:\n"
				+ ex.getCause ().getLocalizedMessage ());
			return 3;
		}
		catch (ConstructStrategyException ex) {
			System.err.println ("Error creating an instance of a strategy of game '"
				+ this.description.getClass ().getName ()
				+ "\nCause was:\n"
				+ ex.getCause ().getLocalizedMessage ());
			return 3;
		}
		catch (IOException ex) {
			System.err.println ("Error writing data to the database.\nDetailed info:\n");
			ex.printStackTrace (System.err);
			return 3;
		}
		EvolutionaryAlgorithm ea;
		ea = new EvolutionaryAlgorithm (config.getGame (), config.getPopulation ());
		ea.run ();
		try {
			Database.singleton.close ();
		}
		catch (IOException ex) {
			System.err.println ("Error closing the database");
			return 4;
		}
		return 0;
	}
/*
	private int run (String[] args)
	{
		if (args.length != 1) {
			System.err.println ("Usage:\n java intopo.evogame.partnerselection.Main GAME\n");
			return 1;
		}
		try {
			Database.singleton.open (false);
			TextConfigFilePlainPlayers<? extends Game<?>, ? extends Strategy> cf;
			if (args [0].equals ("gt")) {
				cf = TextConfigFilePlainPlayers.readGiveTake ();
			}
//			else if (args [0].equals ("pgp")) {
//				cf = TextConfigFilePlainPlayers.readPublicGoodProvision ();
//			}
			else {
				System.err.println ("Unkown game");
				return 1;
			}
			EvolutionaryAlgorithm<? extends Game<?>, ? extends Strategy<?>, ? extends AbstractPlayer<?, ?, ?>> ea;
			ea = new EvolutionaryAlgorithm (cf.game, cf.population);
			cf.population.debug ();
			ea.run ();
			Database.singleton.close ();
		}
		catch (FileNotFoundException ex) {
			System.err.println ("Error opening file config.txt");
			ex.printStackTrace ();
			return 1;
		}
		catch (Exception ex) {
			ex.printStackTrace ();
			return 1;
		}
		return 0;
	}
	*/
	static public void main (String[] args)
	{
		System.exit (new Main (args).run ());
//		new Main ().run (args);
	}
}

// Local Variables:
// mode: java
// mode: flyspell-prog
// ispell-local-dictionary: "british"
// End:
